package login

import (
	"fmt"
	codecs "sanguo/codec/cs"
	"sanguo/cs"
	"sanguo/node/client/dispatcher"
	cs_msg "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
	"github.com/sniperHW/kendynet"
	"github.com/sniperHW/kendynet/event"
	"github.com/sniperHW/kendynet/golog"
)

var processQueue *event.EventQueue

type loginCallback func(kendynet.StreamSession, *dispatcher.Dispatcher, *codecs.Message, error)

func onGameEstablish(args []interface{}) {

	session := args[0].(kendynet.StreamSession)
	userID := args[1].(string)
	token := args[2].(string)
	gameDispatcher := args[3].(*dispatcher.Dispatcher)
	lcallback := args[4].(loginCallback)

	gameLoginToS := &cs_msg.GameLoginToS{
		UserID:   proto.String(userID),
		Token:    proto.String(token),
		ServerID: proto.Int32(1),
	}
	err := session.Send(codecs.NewMessage(uint16(0), gameLoginToS))
	if nil != err {
		fmt.Printf("send error:%s\n", err.Error())
		lcallback(nil, nil, nil, err)
		return
	}

	gameDispatcher.Register(&cs_msg.GameLoginToC{}, true, func(args []interface{}) {
		lcallback(session, gameDispatcher, args[1].(*codecs.Message), nil)
	})
}

func onLoginEstablish(args []interface{}) {
	fmt.Println("onLoginEstablish")
	session := args[0].(kendynet.StreamSession)
	userID := args[1].(string)
	loginDispatcher := args[2].(*dispatcher.Dispatcher)
	lcallback := args[3].(loginCallback)

	loginToS := &cs_msg.LoginToS{
		UserID: proto.String(userID),
	}
	err := session.Send(codecs.NewMessage(uint16(0), loginToS))
	if nil != err {
		fmt.Printf("send error:%s\n", err.Error())
		return
	}

	loginDispatcher.Register(&cs_msg.LoginToC{}, true, func(args []interface{}) {

		loginToC := args[1].(*codecs.Message).GetData().(*cs_msg.LoginToC)

		code := loginToC.GetCode()
		game := loginToC.GetGame()
		token := loginToC.GetToken()

		fmt.Println(code, game, token)

		if code == cs_msg.EnumType_OK {
			gameDispatcher := dispatcher.New(processQueue)
			gameDispatcher.Register("Establish", true, func(args []interface{}) {
				args = append(args, userID)
				args = append(args, token)
				args = append(args, gameDispatcher)
				args = append(args, lcallback)
				onGameEstablish(args)
			})
			cs.DialTcp(game, 0, gameDispatcher)
		}
	})
}

func init() {

	outLogger := golog.NewOutputLogger("log", "client", 1024*1024*1000)
	kendynet.InitLogger(outLogger, "client")

	processQueue = event.NewEventQueue()
	go func() {
		processQueue.Run()
		fmt.Println("queue break-------------")
	}()
}

func Login(userID, addr string, callback loginCallback) {

	fmt.Println(userID, addr)

	loginDispatcher := dispatcher.New(processQueue)
	loginDispatcher.Register("Establish", true, func(args []interface{}) {
		args = append(args, userID)
		args = append(args, loginDispatcher)
		args = append(args, callback)
		onLoginEstablish(args)
	})
	cs.DialTcp(addr, 0, loginDispatcher)
}
